#####################################################################
# Product:      KnowledgeEngine (Plone Edition)
#
# File:         DatetimeSelectorEditlet.py
#
# Copyright:    Copyright (c) 2006, Faulkner Technologies
#
# Author:       Tinh Truong
#
# Description:  This file defines the DateTimeEditlet class, that is
#               used to generate date/time editlets for property editors.
#
#               It's implementation is based on the LGPL DHTML
#               DateTimeChooser By DynArch.
#               (http://www.dynarch.com/projects/calendar/)
#
#               It uses the Zope DateTime to represent dates and time.
#
# See Also:     PropertyEditlet, PropertyRefleciton, 
#               PropertyDefinition, PropertyAccess 
#####################################################################

#####################################################################
## KnowledgeEngine Library Imports
from Products.KnowledgeEngine.Common import *
from Products.KnowledgeEngine.Core import *
from Products.KnowledgeEngine.Editlet import Editlet
from Products.KnowledgeEngine.PropertyDefinition import *
from Products.KnowledgeEngine.PropertyTypes import *
from Products.KnowledgeEngine.PropertyFormats import *
from Products.KnowledgeEngine.PropertyStructures import *

#####################################################################
## Zope Library Imports
from DateTime import DateTime
 
#####################################################################
## Python Library Imports
# (none)

#####################################################################
## DateTimeEditlet Class Definition
class DatetimeSelectorEditlet(Editlet):
    """
        An editlet for editing date time properties  
    """
    
    #---------------------------------------------------------------#
    
    def isEditable(self, propertyDefinition, propertyAccess=None, value=None, isForConstructor=false, REQUEST=None, context=None):
        """
            Returns if the specified propertyDefinition can be
            edited by this editlet
        """
        
        #return propertyDefinition.getType() == pt_STRING and propertyDefinition.getStructure() == ps_ATOMIC and (propertyDefinition.getFormat() == pf_NATIVE or propertyDefinition.getFormat() == pf_TEXT_SINGLELINE) and not propertyDefinition.hasEnumeratedValues()        
        return propertyDefinition.getType() in [pt_DATETIMESELECTOR] and propertyDefinition.getStructure() == ps_ATOMIC and propertyDefinition.getFormat() == pf_NATIVE
        
    #---------------------------------------------------------------#

    def generateEditorFor(self, propertyDefinition, propertyAccess=None, value=None, isForConstructor=false, REQUEST=None, context=None):
        """
            Returns a HTML editlet for the specified property.
        """

        #ensure that we use a writeable editlet (if possible) if we are dealing with a mandatory property and we don't yet have a value
        if propertyDefinition.isMandatory() and propertyAccess is not None and (not hasattr(propertyAccess, propertyDefinition.getIdentity()) or getattr(propertyAccess, propertyDefinition.getIdentity()) is None):
            
            #we want an editletEVAP with the most permissions (which may not include write access)
            editletEVAP = propertyDefinition.getConstructorEVAP() | propertyDefinition.getPropertyEditorEVAP()
        
        else:
            #determine the type of editlet we need to produce based on editlet value access permission (EVAM)
            editletEVAP = iif(isForConstructor, propertyDefinition.getConstructorEVAP(), propertyDefinition.getPropertyEditorEVAP())
                
        #-----------------
        #no property editor is required
        if editletEVAP == evap_NONE:
            result = ""

        #-----------------
        #a read-only property editor is required
        elif editletEVAP == evap_READONLY:

            #get the value for the property
            if isForConstructor or propertyAccess is None:
                value = propertyDefinition.getDefaultValue()
            else:
                value = propertyAccess.getPropertyValue(propertyDefinition.getIdentity())

            #ensure the value is not none!
            if value is None:
                value = DateTime()
            
            #create the editor
            result = "<table border=1><tr><td>%s</td></tr></table>" % (value,)
        
        #-----------------
        #a writeable property editor is required
        else: 
       
            #get the value for the property (if possible)
            if editletEVAP == evap_WRITEONLY:
                #use the current date
                value = DateTime()
            else:
                if isForConstructor or propertyAccess is None:
                    value = propertyDefinition.getDefaultValue()
                else:
                    #get the value for the property
                    value = propertyAccess.getPropertyValue(propertyDefinition.getIdentity())

            #ensure the value is not none!
            if value is None:
                value = DateTime()
        
            #create the editlet
            result = "<input type=\"text\" id=\"%s\" name=\"ke%s\" size=\"%s\" value=\"%s\">" % (propertyDefinition.getIdentity(), propertyDefinition.getIdentity(), 40, toHTML(value))           
                        
        return result        
        
    #---------------------------------------------------------------#

    def containsPropertyValue(self, propertyDefinition, REQUEST):
        """
            Determines if the provided request contains
            a value for the specified propertyDefinition.
            
            This method is used (and is useful for) determining and
            updating the values of properties from property editors.
            
            All editlet implementations must override this method.            
        """
        
        return REQUEST.has_key("ke%s" % (propertyDefinition.getIdentity(),)) or REQUEST.has_key('kedefaultDatetime')
        
    #---------------------------------------------------------------#

    def updatePropertyWith(self, propertyDefinition, propertyAccess, REQUEST=None):
        """
            Attempts to update the specified property on the
            object implementing the PropertyAccess interface with the
            specified HTTP REQUEST.
        """
        dateTime = ""
        if propertyDefinition.getIdentity() == "defaultDatetime":
            dateTimeValue = REQUEST['kedefaultDatetime']
           
            try:
               dateTimeCheck =  DateTime(dateTimeValue)
               dateTime = dateTimeValue
            except:
                if len(dateTimeValue) > 0:
                    if dateTimeValue.find('now +') != -1 or dateTimeValue.find('now+') != -1:
                        valueComponent = dateTimeValue.split('+')
                        d = DateTime() + valueComponent[1]
                        dateTime = d.strftime("%Y-%m-%d %I:%M %p")
                    elif dateTimeValue.find('now -') != -1 or dateTimeValue.find('now-') != -1:
                        valueComponent = dateTimeValue.split('-')
                        d = DateTime() - valueComponent[1]
                        dateTime = d.strftime("%Y-%m-%d %I:%M %p")
                    else:
                        d = DateTime()
                        dateTime = d.strftime("%Y-%m-%d %I:%M %p")

            # Check we have a value if it isMandatory
            propertyDefinition.verifyMandatoryValue(dateTime)

            propertyAccess.setPropertyValue(propertyDefinition.getIdentity(), dateTime)
 
        else:       
            #get the value from the request
            value = REQUEST["ke%s" % (propertyDefinition.getIdentity(),)]

            # Check we have a value if it isMandatory
            propertyDefinition.verifyMandatoryValue(value)

            #set the value for the property from the REQUEST
            propertyAccess.setPropertyValue(propertyDefinition.getIdentity(), value)
        
    #---------------------------------------------------------------#

#####################################################################
## Class Initialisation

# Register Editlet Information with the Knowledge Engine
registerEditlet("DatetimeSelectorEditlet", DatetimeSelectorEditlet())

#####################################################################
